﻿using SharPy.WebObjects;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading.Tasks;
using Windows.Data.Json;
using Windows.Storage;

namespace SharPy.GameSaves
{
    /// <summary>
    /// These are used for Json serialization to save file,
    /// file contains a single group of 12 save items
    /// </summary>
    [DataContract]
    public class SaveData
    {
        public SaveData(int uniqueId, String title)
        {
            this.UniqueId = uniqueId;
            this.Title = title;
            this.Groups = new ObservableCollection<SaveDataGroup>();
        }

        [DataMember]
        public int UniqueId { get; private set; }
        [DataMember]
        public string Title { get; private set; }
        [DataMember]
        public ObservableCollection<SaveDataGroup> Groups { get; private set; }

        public override string ToString()
        {
            return this.Title;
        }
    }

    [DataContract]
    public class SaveDataItem
    {
        public SaveDataItem(int uniqueId, String title, int lineNo, String imagePath, String description, String content)
        {
            this.UniqueId = uniqueId;
            this.Title = title;
            this.LineNo = lineNo;
            this.Description = description;
            this.ImagePath = imagePath;
            this.Content = content;
        }

        [DataMember] public int UniqueId { get; private set; }
        [DataMember] public string Title { get; private set; }
        [DataMember] public int LineNo { get; private set; }
        [DataMember] public string Description { get; private set; }
        [DataMember] public string ImagePath { get; private set; }
        [DataMember] public string Content { get; private set; }

        public override string ToString()
        {
            return this.Title;
        }
    }

    /// <summary>
    /// Group
    /// </summary>
    [DataContract]
    public class SaveDataGroup
    {
        public SaveDataGroup(String uniqueId, String title, String subtitle, String imagePath, String description)
        {
            this.UniqueId = uniqueId;
            this.Title = title;
            this.Subtitle = subtitle;
            this.Description = description;
            this.ImagePath = imagePath;
            this.Items = new ObservableCollection<SaveDataItem>();
        }

        [DataMember] public string UniqueId { get; private set; }
        [DataMember] public string Title { get; private set; }
        [DataMember] public string Subtitle { get; private set; }
        [DataMember] public string Description { get; private set; }
        [DataMember] public string ImagePath { get; private set; }
        [DataMember] public ObservableCollection<SaveDataItem> Items { get; private set; }

        public override string ToString()
        {
            return this.Title;
        }
    }

    /// <summary>
    /// </summary>
    public sealed class SaveDataSource
    {
        private static SaveDataSource _SaveDataSource = new SaveDataSource();

        private ObservableCollection<SaveDataGroup> _groups = new ObservableCollection<SaveDataGroup>();
        public ObservableCollection<SaveDataGroup> Groups
        {
            get { return this._groups; }
        }

        public static async Task<SaveDataGroup> GetGroupAsync(string uniqueId, StorageFolder RootFolder)
        {
            await _SaveDataSource.GetDataAsync(RootFolder);
            var matches = _SaveDataSource.Groups.Where((group) => group.UniqueId.Equals(uniqueId));
            if (matches.Count() == 1) return matches.First();
            return null;
        }

        private async Task GetDataAsync(StorageFolder RootFolder)
        {
            JsonObject jsonObject;

            if (this._groups.Count != 0)
                this.Groups.RemoveAt(0);

            StorageFile f = await File_Management.clFileHelper.GetSaveFile(RootFolder);

            if (f == null)
            {
                f = await File_Management.clFileHelper.CreateEmptySaveFile(RootFolder);
            }

            string jsonText = await FileIO.ReadTextAsync(f);

            try
            {
                jsonObject = JsonObject.Parse(jsonText);
            }
            catch (Exception e)
            {
                jsonObject = null;
            }

            if (jsonObject == null)
                if (await SharPy.Interface.clDialogs.SaveFileCorrupt())
                {
                    f = await File_Management.clFileHelper.CreateEmptySaveFile(RootFolder);
                    jsonText = await FileIO.ReadTextAsync(f);
                    jsonObject = JsonObject.Parse(jsonText);
                }
                else return;

            JsonArray jsonArray = jsonObject["Groups"].GetArray();

            foreach (JsonValue groupValue in jsonArray)
            {
                JsonObject groupObject = groupValue.GetObject();
                SaveDataGroup group = new SaveDataGroup(groupObject["UniqueId"].GetString(),
                                                            groupObject["Title"].GetString(),
                                                            groupObject["Subtitle"].GetString(),
                                                            groupObject["ImagePath"].GetString(),
                                                            groupObject["Description"].GetString());

                foreach (JsonValue itemValue in groupObject["Items"].GetArray())
                {
                    JsonObject itemObject = itemValue.GetObject();
                    group.Items.Add(new SaveDataItem((int)itemObject["UniqueId"].GetNumber(),
                                                        itemObject["Title"].GetString(),
                                                        (int)itemObject["LineNo"].GetNumber(),
                                                        itemObject["ImagePath"].GetString(),
                                                        itemObject["Description"].GetString(),
                                                        itemObject["Content"].GetString()));
                }
                this.Groups.Add(group);

            }
        }
    }
}